package com.example.backend.config;

import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.ThreadMXBean;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 性能监控和告警配置
 * 提供系统性能指标监控和异常告警
 */
@Configuration
@EnableScheduling
public class PerformanceMonitoringConfig {

    /**
     * 性能指标收集器
     */
    @Component
    public static class PerformanceMetrics {
        
        private final AtomicLong requestCount = new AtomicLong(0);
        private final AtomicLong errorCount = new AtomicLong(0);
        private final AtomicLong totalResponseTime = new AtomicLong(0);
        private final AtomicLong maxResponseTime = new AtomicLong(0);
        private final AtomicLong minResponseTime = new AtomicLong(Long.MAX_VALUE);
        
        // 内存使用统计
        private final MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
        private final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
        
        public void recordRequest(long responseTime) {
            requestCount.incrementAndGet();
            totalResponseTime.addAndGet(responseTime);
            
            // 更新最大响应时间
            long currentMax = maxResponseTime.get();
            while (responseTime > currentMax && !maxResponseTime.compareAndSet(currentMax, responseTime)) {
                currentMax = maxResponseTime.get();
            }
            
            // 更新最小响应时间
            long currentMin = minResponseTime.get();
            while (responseTime < currentMin && !minResponseTime.compareAndSet(currentMin, responseTime)) {
                currentMin = minResponseTime.get();
            }
        }
        
        public void recordError() {
            errorCount.incrementAndGet();
        }
        
        public long getRequestCount() {
            return requestCount.get();
        }
        
        public long getErrorCount() {
            return errorCount.get();
        }
        
        public double getAverageResponseTime() {
            long count = requestCount.get();
            return count > 0 ? (double) totalResponseTime.get() / count : 0;
        }
        
        public long getMaxResponseTime() {
            return maxResponseTime.get();
        }
        
        public long getMinResponseTime() {
            return minResponseTime.get() == Long.MAX_VALUE ? 0 : minResponseTime.get();
        }
        
        public double getErrorRate() {
            long total = requestCount.get();
            return total > 0 ? (double) errorCount.get() / total * 100 : 0;
        }
        
        public long getUsedMemory() {
            return memoryBean.getHeapMemoryUsage().getUsed();
        }
        
        public long getMaxMemory() {
            return memoryBean.getHeapMemoryUsage().getMax();
        }
        
        public double getMemoryUsagePercent() {
            long max = getMaxMemory();
            return max > 0 ? (double) getUsedMemory() / max * 100 : 0;
        }
        
        public int getThreadCount() {
            return threadBean.getThreadCount();
        }
        
        public int getPeakThreadCount() {
            return threadBean.getPeakThreadCount();
        }
        
        // 重置统计信息
        public void reset() {
            requestCount.set(0);
            errorCount.set(0);
            totalResponseTime.set(0);
            maxResponseTime.set(0);
            minResponseTime.set(Long.MAX_VALUE);
        }
    }

    /**
     * 系统健康检查指示器
     */
    @Component
    public static class SystemHealthIndicator implements HealthIndicator {
        
        private final PerformanceMetrics metrics;
        
        public SystemHealthIndicator(PerformanceMetrics metrics) {
            this.metrics = metrics;
        }
        
        @Override
        public Health health() {
            try {
                // 检查内存使用率
                double memoryUsage = metrics.getMemoryUsagePercent();
                if (memoryUsage > 90) {
                    return Health.down()
                            .withDetail("memory", "内存使用率过高: " + String.format("%.2f", memoryUsage) + "%")
                            .withDetail("used", metrics.getUsedMemory())
                            .withDetail("max", metrics.getMaxMemory())
                            .build();
                }
                
                // 检查错误率
                double errorRate = metrics.getErrorRate();
                if (errorRate > 10) {
                    return Health.down()
                            .withDetail("errorRate", "错误率过高: " + String.format("%.2f", errorRate) + "%")
                            .withDetail("errors", metrics.getErrorCount())
                            .withDetail("requests", metrics.getRequestCount())
                            .build();
                }
                
                // 检查响应时间
                double avgResponseTime = metrics.getAverageResponseTime();
                if (avgResponseTime > 5000) { // 5秒
                    return Health.down()
                            .withDetail("responseTime", "平均响应时间过长: " + String.format("%.2f", avgResponseTime) + "ms")
                            .withDetail("max", metrics.getMaxResponseTime())
                            .withDetail("min", metrics.getMinResponseTime())
                            .build();
                }
                
                // 检查线程数
                int threadCount = metrics.getThreadCount();
                if (threadCount > 200) {
                    return Health.down()
                            .withDetail("threads", "线程数过多: " + threadCount)
                            .withDetail("peak", metrics.getPeakThreadCount())
                            .build();
                }
                
                // 系统正常
                return Health.up()
                        .withDetail("memory", String.format("%.2f", memoryUsage) + "%")
                        .withDetail("errorRate", String.format("%.2f", errorRate) + "%")
                        .withDetail("avgResponseTime", String.format("%.2f", avgResponseTime) + "ms")
                        .withDetail("threads", threadCount)
                        .withDetail("requests", metrics.getRequestCount())
                        .build();
                        
            } catch (Exception e) {
                return Health.down()
                        .withDetail("error", e.getMessage())
                        .build();
            }
        }
    }

    /**
     * 性能监控定时任务
     */
    @Component
    public static class PerformanceMonitor {
        
        private final PerformanceMetrics metrics;
        
        public PerformanceMonitor(PerformanceMetrics metrics) {
            this.metrics = metrics;
        }
        
        /**
         * 每分钟检查性能指标
         */
        @Scheduled(fixedRate = 60000)
        public void checkPerformance() {
            try {
                // 检查内存使用率
                double memoryUsage = metrics.getMemoryUsagePercent();
                if (memoryUsage > 85) {
                    System.err.println("⚠️ 内存使用率警告: " + String.format("%.2f", memoryUsage) + "%");
                }
                
                // 检查错误率
                double errorRate = metrics.getErrorRate();
                if (errorRate > 5) {
                    System.err.println("⚠️ 错误率警告: " + String.format("%.2f", errorRate) + "%");
                }
                
                // 检查响应时间
                double avgResponseTime = metrics.getAverageResponseTime();
                if (avgResponseTime > 3000) { // 3秒
                    System.err.println("⚠️ 响应时间警告: " + String.format("%.2f", avgResponseTime) + "ms");
                }
                
                // 打印性能统计
                System.out.println("📊 性能统计 - " +
                    "请求数: " + metrics.getRequestCount() +
                    ", 错误数: " + metrics.getErrorCount() +
                    ", 平均响应时间: " + String.format("%.2f", avgResponseTime) + "ms" +
                    ", 内存使用率: " + String.format("%.2f", memoryUsage) + "%" +
                    ", 线程数: " + metrics.getThreadCount());
                    
            } catch (Exception e) {
                System.err.println("❌ 性能监控异常: " + e.getMessage());
            }
        }
        
        /**
         * 每小时重置统计信息
         */
        @Scheduled(fixedRate = 3600000)
        public void resetMetrics() {
            metrics.reset();
            System.out.println("🔄 性能统计已重置");
        }
        
        /**
         * 每天凌晨2点进行系统健康检查
         */
        @Scheduled(cron = "0 0 2 * * ?")
        public void dailyHealthCheck() {
            System.out.println("🏥 开始每日系统健康检查...");
            
            // 检查数据库连接
            // 检查缓存状态
            // 检查文件系统
            // 生成健康报告
            
            System.out.println("✅ 每日系统健康检查完成");
        }
    }
}